import { Model, DataTypes, Optional } from 'sequelize';
import { sequelize } from '../database';

// 文章属性接口
export interface ArticleAttributes {
  id: string;
  title: string;
  content: string;
  content_html: string;
  summary: string;
  slug: string;
  cover_image: string | null;
  status: 'draft' | 'published' | 'archived';
  view_count: number;
  comment_count: number;
  like_count: number;
  author_id: string;
  category_id: string | null;
  is_pinned: boolean;
  is_featured: boolean;
  reading_time: number;
  meta_title: string | null;
  meta_description: string | null;
  keywords: string | null;
  visibility: 'public' | 'private';
  password: string | null;
  published_at: Date | null;
  created_at: Date;
  updated_at: Date;
  deleted_at: Date | null;
}

// 创建时可选的属性
interface ArticleCreationAttributes extends Optional<ArticleAttributes, 
  'id' | 'content_html' | 'summary' | 'slug' | 'cover_image' | 'view_count' | 
  'comment_count' | 'like_count' | 'is_pinned' | 'is_featured' | 'reading_time' | 
  'meta_title' | 'meta_description' | 'keywords' | 'visibility' | 'password' | 
  'published_at' | 'created_at' | 'updated_at' | 'deleted_at' | 'category_id'> {}

// 文章模型类
class Article extends Model<ArticleAttributes, ArticleCreationAttributes> implements ArticleAttributes {
  public id!: string;
  public title!: string;
  public content!: string;
  public content_html!: string;
  public summary!: string;
  public slug!: string;
  public cover_image!: string | null;
  public status!: 'draft' | 'published' | 'archived';
  public view_count!: number;
  public comment_count!: number;
  public like_count!: number;
  public author_id!: string;
  public category_id!: string | null;
  public is_pinned!: boolean;
  public is_featured!: boolean;
  public reading_time!: number;
  public meta_title!: string | null;
  public meta_description!: string | null;
  public keywords!: string | null;
  public visibility!: 'public' | 'private';
  public password!: string | null;
  public published_at!: Date | null;
  
  // 时间戳
  public readonly created_at!: Date;
  public readonly updated_at!: Date;
  public readonly deleted_at!: Date | null;

  // 计算阅读时间（分钟）
  public static calculateReadingTime(content: string): number {
    const wordsPerMinute = 200; // 假设平均阅读速度为每分钟200个单词
    const words = content.trim().split(/\s+/).length;
    return Math.ceil(words / wordsPerMinute);
  }
}

// 初始化模型
Article.init(
  {
    id: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      primaryKey: true,
    },
    title: {
      type: DataTypes.STRING(200),
      allowNull: false,
      validate: {
        notEmpty: true,
      },
    },
    content: {
      type: DataTypes.TEXT('long'),
      allowNull: false,
    },
    content_html: {
      type: DataTypes.TEXT('long'),
      allowNull: false,
    },
    summary: {
      type: DataTypes.TEXT,
      allowNull: true,
    },
    slug: {
      type: DataTypes.STRING(200),
      allowNull: false,
      unique: true,
    },
    cover_image: {
      type: DataTypes.STRING(255),
      allowNull: true,
    },
    status: {
      type: DataTypes.ENUM('draft', 'published', 'archived'),
      allowNull: false,
      defaultValue: 'draft',
    },
    view_count: {
      type: DataTypes.INTEGER,
      allowNull: false,
      defaultValue: 0,
    },
    comment_count: {
      type: DataTypes.INTEGER,
      allowNull: false,
      defaultValue: 0,
    },
    like_count: {
      type: DataTypes.INTEGER,
      allowNull: false,
      defaultValue: 0,
    },
    author_id: {
      type: DataTypes.UUID,
      allowNull: false,
      references: {
        model: 'users',
        key: 'id',
      },
    },
    category_id: {
      type: DataTypes.UUID,
      allowNull: true,
      references: {
        model: 'categories',
        key: 'id',
      },
    },
    is_pinned: {
      type: DataTypes.BOOLEAN,
      allowNull: false,
      defaultValue: false,
    },
    is_featured: {
      type: DataTypes.BOOLEAN,
      allowNull: false,
      defaultValue: false,
    },
    reading_time: {
      type: DataTypes.INTEGER,
      allowNull: false,
      defaultValue: 0,
    },
    meta_title: {
      type: DataTypes.STRING(200),
      allowNull: true,
    },
    meta_description: {
      type: DataTypes.TEXT,
      allowNull: true,
    },
    keywords: {
      type: DataTypes.STRING(255),
      allowNull: true,
    },
    visibility: {
      type: DataTypes.ENUM('public', 'private'),
      allowNull: false,
      defaultValue: 'public',
    },
    password: {
      type: DataTypes.STRING(100),
      allowNull: true,
    },
    published_at: {
      type: DataTypes.DATE,
      allowNull: true,
    },
    created_at: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: DataTypes.NOW,
    },
    updated_at: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: DataTypes.NOW,
    },
    deleted_at: {
      type: DataTypes.DATE,
      allowNull: true,
    },
  },
  {
    sequelize,
    modelName: 'article',
    tableName: 'articles',
    timestamps: true,
    paranoid: true, // 软删除
    underscored: true, // 使用下划线命名法
    hooks: {
      beforeCreate: (article: Article) => {
        // 生成摘要（如果未提供）
        if (!article.summary && article.content) {
          const maxLength = 200;
          article.summary = article.content
            .replace(/#+\s+(.*)/g, '') // 移除Markdown标题
            .replace(/\!\[.*\]\(.*\)/g, '') // 移除图片
            .replace(/\[.*\]\(.*\)/g, '') // 移除链接
            .replace(/(\*\*|__)(.*?)(\*\*|__)/g, '$2') // 移除加粗
            .replace(/(\*|_)(.*?)(\*|_)/g, '$2') // 移除斜体
            .replace(/`{1,3}[\s\S]*?`{1,3}/g, '') // 移除代码块
            .replace(/\n/g, ' ') // 移除换行
            .trim()
            .substring(0, maxLength) + (article.content.length > maxLength ? '...' : '');
        }

        // 计算阅读时间
        if (article.content) {
          article.reading_time = Article.calculateReadingTime(article.content);
        }
      },
      beforeUpdate: (article: Article) => {
        // 更新阅读时间
        if (article.changed('content')) {
          article.reading_time = Article.calculateReadingTime(article.content);
        }
      },
    },
  }
);

export default Article; 